import 'dart:math';
import 'package:eh_mobile/common/utils/extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

// 灯光颜色取色器
class ColorPicker extends StatefulWidget {
  ColorPicker(
      {super.key,
      this.color = Colors.cyan,
      this.size = 280,
      this.thumbSize = 38,
      this.onColorChange,
      this.onColorChangeEnd});

  Color color;
  double size;
  double thumbSize;
  ValueChanged<Color>? onColorChange;
  ValueChanged<Color>? onColorChangeEnd;

  @override
  State<ColorPicker> createState() => _ColorPickerState();
}

class _ColorPickerState extends State<ColorPicker> {
  late final Offset _topPosition = Offset(0, widget.size / 2);
  late final Offset _center = Offset(widget.size / 2, widget.size / 2);
  late Offset _position = Offset(widget.size / 2, widget.size / 2);
  late Offset _currentOffset = Offset(widget.size / 2, widget.size / 2);
  double _radians = 0;
  late final double _radius = widget.size / 2;
  late double hue = 0;
  late Color _currentColor = widget.color;

  @override
  void initState() {
    super.initState();
    _setColor(widget.color);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        padding: const EdgeInsets.only(left: 18, right: 18, top: 18).r,
        child: Column(
          children: [
            _buildTitleWidget(),
            5.sizedBoxHeight,
            _buildColorPicker()
          ],
        ));
  }

  // 创建顶部标题
  Widget _buildTitleWidget() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(5).r,
            color: _currentColor,
          ),
          width: 18.r,
          height: 18.r,
        ),
        4.sizedBoxWidth,
        Text(
          '#${_currentColor.value.toRadixString(16).toUpperCase().substring(2, 8)}',
          style: 16.ts.copyWith(color: const Color.fromRGBO(222, 222, 222, 1)),
        ),
      ],
    );
  }

// 绘制取色器
  Widget _buildColorPicker() {
    return Stack(
      children: [
        ClipPath(
            clipper: ColorPickerClipper(),
            child: Container(
              width: widget.size + 40.r,
              height: widget.size + 40.r,
              alignment: Alignment.center,
              child: GestureDetector(
                onPanDown: _onPanDown,
                onPanUpdate: _onPanUpdate,
                onPanEnd: _onPanEnd,
                child: Container(
                  alignment: Alignment.center,
                  width: widget.size,
                  height: widget.size,
                  child: Stack(
                    alignment: Alignment.center,
                    children: [
                      CustomPaint(
                        painter: CircularColorPainter(
                          center: _center,
                          radius: _radius,
                          colorList: [],
                        ),
                        child: Container(
                          alignment: Alignment.center,
                          width: widget.size,
                          height: widget.size,
                        ),
                      )
                    ],
                  ),
                ),
              ),
            )),
        Thumb(
          top: _currentOffset.dy + 20.r,
          left: _currentOffset.dx + 20.r,
          thumbSize: widget.thumbSize,
          color: _currentColor,
        ),
      ],
    );
  }

  ///获取象限
  static int getQuadrant(double x, double y, double size) {
    if (x >= size / 2) {
      return y >= size / 2 ? 3 : 4;
    }
    return y >= size / 2 ? 2 : 1;
  }

  // 根据传入的颜色换算具体坐标
  void _setColor(Color color) {
    var hsvColor = HSVColor.fromColor(color);
    // 根据饱和度计算出圆盘中具体的半径位置
    double r = hsvColor.saturation * (_radius - _radius * 0.4) + _radius * 0.4;
    double radian = (hsvColor.hue + 180) / -180.0 * pi;
    _updateSelector(r * cos(radian), -r * sin(radian));
    _currentColor = color;
  }

  void _updateSelector(double eventX, double eventY) {
    //更新选中颜色值
    double r = sqrt(eventX * eventX + eventY * eventY);
    double x = eventX, y = eventY;
    if (r > _radius) {
      x *= _radius / r;
      y *= _radius / r;
    }
    _currentOffset = Offset(x + _radius, y + _radius);
    setState(() {});
  }

// 手势监听
  _onPanDown(DragDownDetails details) {
    _change(details);
  }

  _onPanUpdate(DragUpdateDetails details) {
    _change(details);
  }

  _onPanEnd(DragEndDetails details) {
    if (widget.onColorChangeEnd != null) {
      widget.onColorChangeEnd!(_currentColor);
    }
  }

  // 根据手势位置计算颜色
  _change(details) {
    _position = Offset(details.localPosition.dx, details.localPosition.dy);

    double cosA;
    double x = (sqrt(pow((_topPosition.dx - _center.dx), 2) +
        pow((_topPosition.dy - _center.dy), 2)));
    double y = (sqrt(pow((_position.dx - _center.dx), 2) +
        pow((_position.dy - _center.dy), 2)));
    double z = (sqrt(pow((_topPosition.dx - _position.dx), 2) +
        pow((_topPosition.dy - _position.dy), 2)));
    cosA = (x * x + y * y - z * z) / (2 * x * y);
    int quadrant = getQuadrant(_position.dx, _position.dy, _center.dx * 2);
    _radians = acos(cosA);
    if (quadrant == 1 || quadrant == 4) {
      _radians = acos(cosA);
    } else if (quadrant == 2 || quadrant == 3) {
      _radians = 2 * pi - acos(cosA);
    }
    hue = 360 * _radians / (2 * pi);
    // print('radians:${radians} hue:${hue}');
    _currentColor = HSVColor.fromAHSV(1, hue, 1, 1).toColor();
    if (y <= _center.dx) {
      _currentOffset =
          Offset(details.localPosition.dx, details.localPosition.dy);
    } else {
      double dx = _position.dx - _center.dx;
      double dy = _position.dy - _center.dy;
      double distance = sqrt(dx * dx + dy * dy);
      double ratio = _radius / distance;
      _currentOffset = Offset(dx * ratio + _center.dx, dy * ratio + _center.dy);
    }
    if (y <= _center.dx * 0.4) {
      _currentColor = Colors.white;
    } else {
      double distance = (_currentOffset - _center).distance;
      // 通过计算从
      _currentColor = _gradientColor(
          const Color.fromRGBO(255, 255, 255, 1),
          _currentColor,
          (_radius - _center.dx * 0.4).toInt(),
          (distance - _center.dx * 0.4).toInt());
    }

    if (widget.onColorChange != null) {
      widget.onColorChange!(_currentColor);
    }
    setState(() {});
  }

  // 计算从中心点渐变到边缘位置区间里具体位置的颜色
  late int _startR, _startG, _startB, _endR, _endG, _endB;
  late double _sR, _sG, _sB;

  Color _gradientColor(
      Color startColor, Color endColor, int maxStep, int step) {
    _startR = startColor.red;
    _startG = startColor.green;
    _startB = startColor.blue;
    _endR = endColor.red;
    _endG = endColor.green;
    _endB = endColor.blue;
    _sR = (_endR - _startR) / maxStep; //总差值
    _sG = (_endG - _startG) / maxStep;
    _sB = (_endB - _startB) / maxStep;

    return Color.fromRGBO((_startR + _sR * step).toInt(),
        (_startG + _sG * step).toInt(), (_startB + _sB * step).toInt(), 1);
  }
}

// 绘制色盘
class CircularColorPainter extends CustomPainter {
  CircularColorPainter(
      {required this.center, required this.radius, required this.colorList});
  double radius;
  Offset center;
  List<Color> colorList;
  @override
  void paint(Canvas canvas, Size size) {
    var rect = Rect.fromLTWH(0, 0, radius * 2, radius * 2);

    Paint paint = Paint()
      ..style = PaintingStyle.fill
      ..strokeWidth = 1
      ..color = Colors.white;
    // 绘制扇形颜色
    for (double angle = -180; angle < 180; angle += 1) {
      double startAngleRad = pi * (angle) / 180;
      double endAngleRad = pi * ((angle + 1)) / 180;
      Color color =
          HSVColor.fromAHSV(1.0, (angle + 180).toDouble(), 1.0, 1.0).toColor();
      Gradient gradient1 = RadialGradient(
          colors: [Colors.white, Colors.white, color],
          stops: const [0.0, 0.4, 1.0]);
      // paint.color = color;
      paint.shader = gradient1.createShader(rect);

      canvas.drawArc(Rect.fromCircle(center: center, radius: radius),
          startAngleRad, endAngleRad - startAngleRad, true, paint);
    }
    Paint paint2 = Paint()
      ..style = PaintingStyle.fill
      ..strokeWidth = 1
      ..color = Colors.white;
    // 中心圆心绘制
    var rect2 = Rect.fromCircle(center: center, radius: radius * 0.4);
    paint2.color = const Color.fromRGBO(255, 255, 255, 1.0);
    canvas.drawArc(rect2, -pi / 2, 2 * pi, true, paint2);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

class Thumb extends StatelessWidget {
  const Thumb({
    super.key,
    required double top,
    required double thumbSize,
    required double left,
    required Color color,
  })  : _top = top,
        _thumbsize = thumbSize,
        _left = left,
        _color = color;

  final double _top;
  final double _thumbsize;
  final double _left;
  final Color _color;

  @override
  Widget build(BuildContext context) {
    return Positioned(
        top: _top - _thumbsize / 2,
        left: _left - _thumbsize / 2,
        child: IgnorePointer(
          child: Container(
            width: _thumbsize,
            height: _thumbsize,
            decoration: BoxDecoration(
                color: _color,
                borderRadius: BorderRadius.circular(
                  _thumbsize / 2,
                ),
                boxShadow: const [
                  BoxShadow(
                    blurRadius: 10, //阴影范围
                    color: Color.fromRGBO(0, 0, 0, 0.50), //阴影颜色
                  ),
                ],
                border: Border.all(color: Colors.white, width: 3)),
          ),
        ));
  }
}

// 自定义绘制路径 切割出一个带弧形的contaner用于限制手势范围
class ColorPickerClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    path.moveTo(size.width / 2.0, 0);
    path.arcToPoint(Offset(size.width / 2.0, size.width),
        clockwise: false, radius: Radius.circular(size.width / 2.0));
    path.moveTo(size.width / 2.0, size.width);
    path.arcToPoint(Offset(size.width / 2.0, 0),
        clockwise: false, radius: Radius.circular(size.width / 2.0));
    return path;
  }

  @override
  bool shouldReclip(ColorPickerClipper oldClipper) => true;
}
